#pragma once

#include "ApplicationConfig.h"
#include "cuda_runtime.h"

extern "C" {


struct KeyValue {
    uint32_t key;
    uint32_t value;
};

const uint32_t kHashTableCapacity = 128 * 1024 * 1024;
const uint32_t kNumKeyValues = kHashTableCapacity / 2;
const uint32_t kEmpty = 0xffffffff;

// for host
static int32_t h_map_size = 0;
uint32_t read_map_size();
void set_map_size();  // used in host clean_hashtableKeyValue* create_hashtable();
void destroy_hashtable(KeyValue *hashtable);
void clean_hashtable(KeyValue *hashtable);
void insert_hashtable(KeyValue *hashtable, const KeyValue *kvs, uint32_t num_kvs);
void lookup_hashtable(KeyValue *hashtable, KeyValue *kvs, uint32_t num_kvs);
void delete_hashtable(KeyValue *hashtable, const KeyValue *kvs, uint32_t num_kvs);
std::vector<KeyValue> iterate_hashtable(KeyValue *hashtable);

__global__ void gpu_hashtable_insert(KeyValue *hashtable, const KeyValue *kvs, unsigned int numkvs);
__global__ void gpu_hashtable_lookup(KeyValue *hashtable, KeyValue *kvs, unsigned int numkvs);
__global__ void gpu_hashtable_delete(KeyValue *hashtable, const KeyValue *kvs, unsigned int numkvs);
__global__ void gpu_iterate_hashtable(KeyValue *pHashTable, KeyValue *kvs, uint32_t *kvs_size);

// for device
__device__ static uint32_t d_map_size = 0;
__device__ uint32_t hash(uint32_t k);
// ** 此实现针对于统计有哪几种数值的hashtable,不是常规类型，需要注意. 后续会实现更加通用的类型 **
__device__ void device_gpu_hashtable_insert(KeyValue *hashtable, const KeyValue *kvs, unsigned int numkvs);

}